<!-- eslint-disable vue/no-mutating-props -->
<template>
  <el-form
    class="rev-form"
    ref="form"
    :model="form"
    :rules="rules"
    :label-width="formConfig.labelWidth"
    :label-position="formConfig.labelPosition"
    v-if="fields"
  >
    <template v-for="col in fields" :key="col.key">
      <el-form-item :label="col.name" :required="col.require" :prop="col.key">
        <el-input v-if="col.type === 'string'" v-model="col.value" />
        <el-input
          v-else-if="col.type === 'textarea' || col.type === 'text'"
          type="textarea"
          :rows="col.rows || 10"
          v-model="col.value"
        />
        <el-input v-else-if="col.type === 'number'" type="number" v-model="col.value" />
        <el-input v-else-if="col.type === 'int'" type="number" v-model="col.value" />
        <el-input v-else-if="col.type === 'float'" type="number" v-model="col.value" />
        <el-input
          v-else-if="col.type === 'password'"
          type="password"
          show-password
          v-model="col.value"
        />
        <el-select
          v-else-if="col.type === 'enum'"
          filterable
          clearable
          allow-create
          v-model="col.value"
          placeholder="请选择"
        >
          <template v-for="(val, index) in col.values" :key="index">
            <el-option v-if="typeof val === 'object'" :label="val.name" :value="val.key" />
            <el-option v-else :label="val" :value="val" />
          </template>
        </el-select>
        <el-select
          v-else-if="col.type === 'list'"
          filterable
          clearable
          allow-create
          multiple
          collapse-tags
          v-model="col.value"
          placeholder="请选择"
        >
          <template v-for="(val, index) in col.values" :key="index">
            <el-option v-if="typeof val === 'object'" :label="val.name" :value="val.key" />
            <el-option v-else :label="val" :value="val" />
          </template>
        </el-select>
        <el-slider
          v-else-if="col.type === 'range'"
          v-model="col.value"
          size="small"
          :min="col.range[0]"
          :max="col.range[1]"
          :step="col.step || 1"
          show-input
          :show-input-controls="false"
        />
        <el-date-picker
          v-else-if="col.type === 'datetime'"
          v-model="col.value"
          type="datetime"
          placeholder="选择日期时间"
        />
        <el-checkbox v-else-if="col.type === 'bool'" v-model="col.value" />
        <template v-else-if="col.type === 'file'">
          <meta-upload v-model="col.value" :meta="col" :spec="false" />
        </template>
        <template v-else-if="col.type === 'fileset'">
          <meta-upload v-model="col.value" :meta="col" multiple />
        </template>
        <div v-else-if="col.type === 'html'" v-html="col.value"></div>
      </el-form-item>
    </template>
  </el-form>
</template>

<script>
import MetaUpload from './meta/Upload.vue'
import { getFormValues } from '@/api/basic'
import { useCache } from '@/hooks/web/useCache'
const { wsCache } = useCache()
export default {
  name: 'RevForm',
  components: { MetaUpload },
  props: {
    fields: {
      type: Array,
      default: () => []
    },
    config: {
      type: Object,
      default: () => ({})
    }
  },
  data() {
    return {
      fileList: [],
      token: wsCache.get('Admin-Token')
    }
  },
  computed: {
    form() {
      return this.fields.reduce((t, c) => {
        t[c.key] = c.value
        return t
      }, {})
    },
    rules() {
      return this.fields.reduce((t, c) => {
        if (c.require) {
          t[c.key] = [
            {
              required: true,
              message:
                (['enum', 'list', 'file', 'fileset'].includes(c.type) ? '请选择' : '请输入') +
                c.name,
              trigger: ['enum', 'list', 'file', 'fileset'].includes(c.type)
                ? ['change', 'blur']
                : 'blur'
            }
          ]
        }
        return t
      }, {})
    },
    formConfig() {
      return {
        labelWidth: '120px',
        labelPosition: 'right',
        ...this.config
      }
    }
  },
  watch: {
    fields(val) {
      // this.initRemoteValues()
    }
  },
  mounted() {
    // this.initRemoteValues()
  },
  methods: {
    async validate(callback) {
      return this.$refs.form.validate(callback)
    },
    resetFields() {
      this.$nextTick(() => {
        this.$refs.form.resetFields()
      })
    },
    beforeRemove(file) {
      return this.$confirm(`确定移除 ${file.name}？`)
    },
    // initRemoteValues() {
    //   const reqFields = this.fields.filter(
    //     (col) => ['enum', 'list'].includes(col.type) && col.source
    //   )
    //   const reqPromise = reqFields.map((col) => getFormValues({ source: col.source }))
    //   Promise.all(reqPromise).then((res) => {
    //     res.forEach((r, i) => {
    //       reqFields[i].values = r.values
    //     })
    //   })
    // },
    validateField(field) {
      this.$nextTick(() => {
        this.$refs.form.validateField(field)
      })
    }
  }
}
</script>

<style scoped lang="less">
.rev-form {
  :deep(.upload-attachment) {
    .el-upload-list {
      flex: 0 0 400px;
    }

    &.multiple {
      width: 400px;
    }

    &.single {
      display: flex;
      align-items: center;
    }
  }

  :deep(&.el-form--label-top) {
    &.el-form--label-top {
      .el-form-item__label {
        padding-bottom: 0;
      }
      .el-form-item--small.el-form-item {
        margin-bottom: 10px;
      }
    }
  }
}
</style>
